package com.wj.console.common.util;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

/**
 * 资金计算公共类
 * 
 * @author wj
 */
public class FundsUtil {

	/**
	 * 计算利息
	 * 
	 * @author wj
	 * @param amount 金额
	 * @param rate 利率(日息)
	 * @param days 天数
	 * @return 利息额金额 (若参数非法则返回0)
	 */
	public static BigDecimal calInterestAmount(BigDecimal amount, BigDecimal rate, int days) {
		if (amount == null || rate == null || days <= 0) {
			return new BigDecimal(0);
		}
		return rate.multiply(amount).multiply(new BigDecimal(days));
	}

	/**
	 * 计算利息
	 * 
	 * @author wj
	 * @param rate 利率
	 * @param loanDate 借款时间
	 * @param repayDate 还款时间
	 * @return 利息额金额 (若参数非法则返回0)
	 */
	public static BigDecimal calInterestAmount(BigDecimal amount, BigDecimal rate, Date loanDate, Date repayDate) {
		if (rate == null || loanDate == null || repayDate == null) {
			return new BigDecimal(0);
		}
		int between_days = getBetweenDays(loanDate, repayDate);
		if (between_days <= 0) { // 还款时间小于等于借款时间
			return new BigDecimal(0);
		}
		return calInterestAmount(amount, rate, (int) between_days);
	}

	/**
	 * 获取日期相差天数
	 * 
	 * @author wj
	 * @param beginDate 开始时间
	 * @param endDate 结束时间
	 * @return 相差天数（若开始时间小于结束时间则返回0）
	 */
	public static int getBetweenDays(Date beginDate, Date endDate) {
		if (beginDate == null || endDate == null) {
			return 0;
		}
		Calendar calBegin = Calendar.getInstance();
		calBegin.setTime(beginDate);
		calBegin.set(Calendar.HOUR_OF_DAY, 0);
		calBegin.set(Calendar.MINUTE, 0);
		calBegin.set(Calendar.SECOND, 0);

		Calendar calend = Calendar.getInstance();
		calend.setTime(endDate);
		calend.set(Calendar.HOUR_OF_DAY, 0);
		calend.set(Calendar.MINUTE, 0);
		calend.set(Calendar.SECOND, 0);

		int between_days = ((int) (calend.getTime().getTime() / 1000) - (int) (calBegin.getTime().getTime() / 1000)) / 3600 / 24 + 1;
		if (between_days <= 0) { // 开始时间小于等于结束时间
			return 0;
		}
		return between_days;
	}

	/**
	 * 计算多少天之后日期
	 * 
	 * @author wj
	 * @param date 日期
	 * @param days 天数
	 * @return 结果日期
	 */
	public static Date plusDays(Date date, int days) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.add(Calendar.DAY_OF_MONTH, days);
		return cal.getTime();
	}

	/**
	 * 计算多少月之后日期
	 * 
	 * @author wangjue
	 * @param date 日期
	 * @param months 月数（可为负数）
	 * @return 结果日期
	 */
	public static Date plusMonths(Date date, int months) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, months);
		return cal.getTime();
	}

	/**
	 * 根据公式计算
	 * 
	 * @author wj
	 * @param formula 公式
	 * @param wage 工资
	 */
	public static BigDecimal calFormulaValue(String formula, BigDecimal wage) throws Exception {
		ScriptEngineManager manager = new ScriptEngineManager();
		ScriptEngine engine = manager.getEngineByName("js");
		engine.put("wage", wage);
		double val = ((Double) engine.eval(formula)).doubleValue();
		BigDecimal res = new BigDecimal(val);
		return res.setScale(0, BigDecimal.ROUND_HALF_UP);
	}
	
	public static BigDecimal calFormulaValue(String formula, BigDecimal argone, BigDecimal argtwo, BigDecimal argthree) throws Exception {
		ScriptEngineManager manager = new ScriptEngineManager();
		ScriptEngine engine = manager.getEngineByName("js");
		engine.put("argone", argone);
		engine.put("argtwo", argtwo);
		engine.put("argthree", argthree);
		double val = ((Double) engine.eval(formula)).doubleValue();
		BigDecimal res = new BigDecimal(val);
		return res.setScale(0, BigDecimal.ROUND_HALF_UP);
	}
	
	/**
	 * 计算月份差值
	 * @author wangjue
	 * @date 2016年6月1日下午2:56:03
	 *
	 * @param beginDate 起始日期
	 * @param endDate   结束日期 <br><font style="color:red">endDate 大于  beginDate</font>
	 * @return
	 */
	public static int getBetweenMonths(Date start,Date end){
		if (start.after(end)) {
            Date t = start;
            start = end;
            end = t;
        }
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(start);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(end);
        Calendar temp = Calendar.getInstance();
        temp.setTime(end);
        temp.add(Calendar.DATE, 1);

        int year = endCalendar.get(Calendar.YEAR)
                - startCalendar.get(Calendar.YEAR);
        int month = endCalendar.get(Calendar.MONTH)
                - startCalendar.get(Calendar.MONTH);

        if ((startCalendar.get(Calendar.DATE) == 1)
                && (temp.get(Calendar.DATE) == 1)) {
            return year * 12 + month + 1;
        } else if ((startCalendar.get(Calendar.DATE) != 1)
                && (temp.get(Calendar.DATE) == 1)) {
            return year * 12 + month;
        } else if ((startCalendar.get(Calendar.DATE) == 1)
                && (temp.get(Calendar.DATE) != 1)) {
            return year * 12 + month;
        } else {
            return (year * 12 + month - 1) < 0 ? 0 : (year * 12 + month);
        }
	}
	

}
